package fun.codedesign.yinxue.util.map;

/**
 * 一种可以通过key来取得第二位或者第三位内容的数据结构，并且key不能重复<br>
 * 采用TreeMap方式来实现 <br>
 *
 * @author zengjian
 * @create 2018-03-15 14:29
 * @since 1.0.0
 */
public class TwoValueMap<K, V1, V2> {

    private Entry<K, V1, V2>[] entrys;
    private int size;

    public static class Entry<K, V1, V2> {
        K key;
        V1 value1;
        V2 value2;
        int index;

        public Entry(K key, V1 value1, V2 value2, int index) {
            this.key = key;
            this.value1 = value1;
            this.value2 = value2;
        }

        public V1 getValue1() {
            return value1;
        }

        public V2 getValue2() {
            return value2;
        }
    }

    public void put(K key, V1 value1, V2 value2) {
        if (size == 0) {
            entrys = new Entry[32];
            entrys[0] = new Entry<>(key, value1, value2, 0);
            size++;
        } else {
            int length = entrys.length;
            for (int i = 0; i < length; i++) {
                // 存在一样的key，更新value1和value2
                if (entrys[i] != null && entrys[i].key.equals(key)) {
                    // 存在key size不变
                    entrys[i].value1 = value1;
                    entrys[i].value2 = value2;
                    break;
                } else if (entrys[i] != null && !entrys[i].key.equals(key)) {
                    // TODO 疑问: 需要把if放进来，以保证 1 if没命中时候，进入 else if 而不是进入else中
                    // 可以将这个if放到else if中&& ，然后else 修改为else if entrys[i] == null ,最后else跳过所有有值但不是与key不想等的元素
                    if (i == length - 1) {
                        // 2倍扩容
                        Entry[] newEntrys = new Entry[(int) (2 * length)];
                        System.arraycopy(entrys, 0, newEntrys, 0, entrys.length);
                        newEntrys[entrys.length] = new Entry<>(key, value1, value2, entrys.length);
                        entrys = newEntrys;
                        size++;
                        break;
                    }
                } else {
                    entrys[i] = new Entry<>(key, value1, value2, i);
                    size++;
                    break;
                }
            }
        }
    }

    private void initEntrys() {
        entrys = new Entry[32];
    }

    public void putValue1(K key, V1 value1) {

    }

    public void putValue2(K key, V2 value2) {

    }

    public V1 getValue1(K key) {
        return getEntry(key) == null ? null : getEntry(key).value1;
    }

    private Entry<K, V1, V2> getEntry(K key) {
        for (int i = 0; i < size; i++) {
            if (entrys[i].key.equals(key)) {
                return entrys[i];
            }
        }
        return null;
    }

    public V2 getValue2(K key) {
        return getEntry(key) == null ? null : getEntry(key).value2;
    }

    public V1 removeValue1(K key) {
        return null;
    }

    public V2 removeValue2(K key) {
        return null;
    }

    public int size() {
        return size;
    }

    public Entry get(int index) {
        return entrys[index];
    }

    public boolean containsKey(K key) {
        return getEntry(key)!=null;
    }

    public void remove(K key) {
        for (int i = 0; i < size(); i++) {
            if (key.equals(entrys[i])) {
                // 将数组往前拷贝一位，并将最后一位元素置null
                Entry oldEntry = entrys[i];
                System.arraycopy(entrys, i + 1, entrys, i, entrys.length - 1 - i);
                entrys[entrys.length - 1] = null;
                size--;
                // return oldEntry;
            }
        }
        // return null;
    }

    public V2[] value2ToArray() {
        V2[] value2s = (V2[]) new Object[size];
        for (int i = 0; i < size; i++) {
            value2s[i] = (V2) get(i).getValue2();
        }
        return value2s;
    }
}
